﻿#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;

#endregion

#region COPYRIGHT

/*
    Copyright (c) 2007, 2008, 2009, 2010 
        Roland Rosenkranz (Glatzemann@email.de)
*/

#endregion

#region LICENSE

/*
    This file is part of starLiGHT.Input.

    starLiGHT.Input is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    starLiGHT.Input is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with starLiGHT.Input.  If not, see <http://www.gnu.org/licenses/>.

    
    ADDITIONAL (commercial) LICENSES for starLiGHT.Input are available on request.
*/

#endregion

#region Version Stuff
// **************[ starLiGHT.Engine SVN ]**********************
// * $Rev:: 1496                  $:  Revision of last commit *
// * $Author:: glatzemann         $:  Author of last commit   *
// * $Date:: 2010-10-11 09:38:05 #$:  Date of last commit     *
// ************************************************************
#endregion

namespace starLiGHT.Input
{
    public class ControlScheme : IEquatable<ControlScheme>, IComparable, IComparable<ControlScheme>
    {
        string name;
        ControlSchemeRule rule;
        public readonly Dictionary<ControlSchemeButton, string> actionMap;
        Dictionary<string, ControlSchemeButton> reverseMap;

        public event ActionTriggerEventHandler ActionTriggered;

        public ControlScheme(string name)
        {
            this.name = name;
            rule = ControlSchemeRule.Overwrite;
            actionMap = new Dictionary<ControlSchemeButton, string>();
            reverseMap = new Dictionary<string, ControlSchemeButton>();
        }

        public void SetAction(ControlSchemeButton button, string action)
        {
            // do we wish to swap, or overwrite?
            if (rule == ControlSchemeRule.Swap)
            {
                // we want to swap if necessary, so check if it's necessary
                if (reverseMap.ContainsKey(action))
                {
                    ControlSchemeButton currentActionButton = reverseMap[action];

                    // if they are, see if it's for different actions
                    if (currentActionButton != button)
                    {
                        // do we actually have true pair to swap with?
                        if (actionMap.ContainsKey(button))
                        {
                            // the current pairing and the new pairing differ, so swap them
                            string currentButtonAction = actionMap[button];

                            actionMap[currentActionButton] = currentButtonAction;
                            reverseMap[currentButtonAction] = currentActionButton;
                        }
                        else
                        {
                            // no true pair, so just remove the current action button map
                            actionMap.Remove(currentActionButton);
                        }
                    }

                    // the reverse map is only used for helping swap operations
                    reverseMap[action] = button;
                }
            }

            // set the map to use the given input-action pair
            actionMap[button] = action;
        }

        public void TriggerAction(Object sender,
                                  ControlSchemeButton button,
                                  InputTriggerType triggerType,
                                  TimeSpan holdDuration)
        {
            // do we have an action attached to this input?
            if (actionMap.ContainsKey(button))
            {
                // do we have some method that will handle the action?
                if (ActionTriggered != null)
                {
                    // fire up the action with the appropriate settings
                    ActionTriggered(sender, new ActionTriggerArgs(actionMap[button], triggerType, holdDuration));
                }
            }
        }

        public string Name
        {
            get { return name; }
        }

        public bool Equals(ControlScheme other)
        {
            return name == other.Name;
        }

        public int CompareTo(object obj)
        {
            if (obj.GetType() == typeof(ControlScheme))
                return name.CompareTo(((ControlScheme)obj).Name);
            else
                return 0;
        }

        public int CompareTo(ControlScheme other)
        {
            return name.CompareTo(other.Name);
        }
    }
}
